import {Component, Input, OnInit, OnDestroy} from '@angular/core';
import {Map, Overlay} from 'ol';
import {HttpService} from '@kylin/http';
import {LayersPanelService} from '../layers-panel/layers-panel.service';
import OverlayPositioning from 'ol/OverlayPositioning';
import * as echarts from 'echarts';
import * as _ from 'lodash';
import {NzMessageService} from 'ng-zorro-antd/message';
import {WKT} from 'ol/format';
import {getCenter} from 'ol/extent';
import {FrontPageService} from '../front-page.service';
import VectorSource from 'ol/source/Vector';
import VectorLayer from 'ol/layer/Vector';

@Component({
    selector: 'kylin-charts',
    templateUrl: './charts.component.html',
    styleUrls: ['./charts.component.less']
})
export class ChartsComponent implements OnInit, OnDestroy {
    @Input() map: Map;

    @Input() set layerId(val) {
        if (val) {
            this.currentLayerId = val;
            this.fetchLayerInfo();
        } else {
            this.currentLayerId = null;
        }
    }

    private currentLayerId = null;
    elementDivs = [];
    chartType = 'pie';
    list: any[] = [];
    currentLayerAttr = [];
    colorList = [
        '#C1232B', '#B5C334', '#FCCE10', '#E87C25', '#27727B',
        '#FE8463', '#9BCA63', '#FAD860', '#F3A43B', '#60C0DD',
        '#D7504B', '#C6E579', '#F4E001', '#F0805A', '#26C0C0'
    ];
    submitLoading = false;

    constructor(
        private http: HttpService,
        public layersPanelService: LayersPanelService,
        private nzMessageService: NzMessageService,
        public frontPageService: FrontPageService
    ) {
    }

    ngOnInit() {
    }

    ngOnDestroy(): void {
        this.clear();
    }

    transferChange(ret: any): void {
        if (ret.from === 'left') {
            ret.list.map(i => {
                this.currentLayerAttr.push(i.key);
            })
        } else {
            ret.list.map(i => {
                _.remove(this.currentLayerAttr, (n) => {
                    return i.key === n;
                })
            })
        }
    }

    clear() {
        this.map.getOverlays().clear();
        this.elementDivs = [];
    }


    createDivs(ids: string[], idPrefix: string): Promise<any> {
        ids.map(i => {
            this.elementDivs.push({id: idPrefix + i});
        });
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve(null);
            }, 0)
        })
    }

    fetchLayerInfo() {
        this.http.get('/layer/getChartData', {layerId: this.currentLayerId})
            .then(res => {
                this.list = [];
                res.data.map(i => {
                    this.list.push({key: i, title: i})
                });
            })
            .catch(err => {

            })
    }

    fetchLayerAttr() {
        this.submitLoading = true;
        if (this.currentLayerAttr.length < 1) {
            this.nzMessageService.warning('请选择图表属性');
            return;
        }
        this.clear();
        this.http.get('/layer/getDataByAttr', {
            layerId: this.currentLayerId,
            attrList: this.currentLayerAttr.toString()
        })
            .then(res => {
                const list = res.data.list;
                if (list.length > 30) {
                    this.nzMessageService.warning(`用于统计的数据已达${list.length}组,页面会有卡顿情况出现,请等待,不建议统计数据大于50组!`);
                }
                list.map(i => {
                    i.center = this.getFeatureCenter(i.the_geom);
                });
                list.map(i => {
                    delete i.the_geom;
                });
                this.createChart(list);
            })
            .catch(err => {

            })
    }

    async createChart(list: any[]) {
        const length = list.length;
        const ids = [];
        for (let i = 0; i < length; i++) {
            ids.push(i);
        }
        const foo = await this.createDivs(ids, 'chart');
        switch (this.chartType) {
            case 'pie':
                list.map((i, index) => {
                    const data = [];
                    _.forIn(i, (v, k) => {
                        if (k !== 'center') {
                            data.push({name: k, value: v})
                        }
                    });
                    this.createPieChart(data, i.center, index);
                });
                break;
            case 'bar':
                list.map((i, index) => {
                    const data = {xAxisData: [], seriesData: []};
                    _.forIn(i, (v, k) => {
                        if (k !== 'center') {
                            data.xAxisData.push(k);
                            data.seriesData.push(v);
                        }
                    });
                    this.createBarChart(data, i.center, index);
                });
                break;
            case 'stacks':
                list.map((i, index) => {
                    const data = {xAxisData: [], seriesData: []};
                    _.forIn(i, (v, k) => {
                        if (k !== 'center') {
                            data.xAxisData.push(k);
                            data.seriesData.push(v);
                        }
                    });
                    this.createStacksChart(data, i.center, index);
                });
                break;
        }
    }

    createPieChart(data: any[], center: number[], index: number) {
        const option: any = {
            tooltip: {
                show: true,
                type: 'showTip',
                x: 0,
                y: 100,
                position: [0, 100]
            },
            toolbox: {
                show: true,
                feature: {
                    mark: {show: true},
                    magicType: {
                        show: true,
                        type: ['pie', 'funnel']
                    },
                }
            },
            calculable: true,
            series: [{
                type: 'pie',
                radius: '60%',
                startAngle: '45',
                label: {
                    normal: {
                        show: false
                    },
                    emphasis: {
                        show: false,
                        textStyle: {
                            color: '#000000',
                            fontWeight: 'bold',
                            fontSize: 16
                        }
                    }
                },
                lableLine: {
                    normal: {
                        show: false
                    },
                    emphasis: {
                        show: false
                    }
                },
                data: data
            }]
        };
        this.addChartToMap(option, index, center);
    }

    createBarChart(data: any, center: number[], index: number) {
        const option: any = {
            tooltip: {
                show: true,
                type: 'showTip',
                x: 0,
                y: 100,
                position: [0, 100]
            },
            xAxis: {
                data: data.xAxisData,
                axisTick: {
                    show: false
                },
                axisLine: {
                    show: false
                },
                axisLabel: {
                    show: false,
                    textStyle: {
                        color: 'red'
                    }
                }
            },
            yAxis: {
                splitLine: {
                    show: false
                },
                axisTick: {
                    show: false
                },
                axisLine: {
                    show: false
                },
                axisLabel: {
                    show: false
                }
            },
            series: [{
                name: '',
                type: 'bar',
                data: data.seriesData,
                itemStyle: {
                    normal: {
                        color: (params) => {
                            return this.colorList[params.dataIndex % this.colorList.length];
                        }
                    }
                },
            }]
        };
        this.addChartToMap(option, index, center);
    }

    createStacksChart(data: any, center: number[], index: number) {
        const option: any = {
            tooltip: {
                show: true,
                type: 'showTip',
                x: 0,
                y: 100,
                position: [0, 100]
            },
            xAxis: {
                splitLine: {
                    show: false
                },
                axisTick: {
                    show: false
                },
                axisLine: {
                    show: false
                },
                axisLabel: {
                    show: false
                }
            },
            yAxis: {

                data: data.xAxisData,
                axisTick: {
                    show: false
                },
                axisLine: {
                    show: false
                },
                axisLabel: {
                    show: false,
                    textStyle: {
                        color: 'red'
                    }
                }
            },
            series: [{
                name: '',
                type: 'bar',
                data: data.seriesData,
                itemStyle: {
                    normal: {
                        color: (params) => {
                            return this.colorList[params.dataIndex % this.colorList.length];
                        }
                    }
                },
            }]
        };

        this.addChartToMap(option, index, center);
    }

    private addChartToMap(eChartsOption: any, index: number, center: number[]) {
        const chartEle = document.getElementById('chart' + index);
        const chart = echarts.init(chartEle);
        chart.setOption(eChartsOption);
        const pie = new Overlay({
            position: center,
            positioning: OverlayPositioning['CENTER_CENTER'],
            element: document.getElementById('chart' + index)
        });
        this.map.addOverlay(pie);
        setTimeout(() => {
            this.submitLoading = false;
        }, 0)
    }

    private getFeatureCenter(data: any): number[] {
        const olFeature = new WKT().readFeature(data);
        const extent = olFeature.getGeometry().getExtent();
        return getCenter(extent);
    }
}
